/**   
 *  This file is part of WaterfallDisplay.

 *  WaterfallDisplay is free software: you can redistribute it and/or modify   
 *  it under the terms of the GNU General Public License as published by   
 *  the Free Software Foundation, either version 3 of the License, or   
 *  (at your option) any later version.

 *  WaterfallDisplay is distributed in the hope that it will be useful,   
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of   
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   
 *  GNU General Public License for more details.

 *  See <http://www.gnu.org/licenses/>.

 */  
package waterfall;

import java.util.Random;

import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.util.Duration;

/**
 * Feeder is used to feed the waterfall display
 * 
 * @author altug.uzunali
 *
 */
public class Feeder {

	private int width;
	private int startPoint = 0;
	private int length = 50;
	private boolean direction = true;
	enum FeederType {
		Random,
		Sinusoidal
	}
	private FeederType feedertype;
	Timeline time = new Timeline();


	public Feeder(final int width, FeederType type) {
		this.width = width;
		this.feedertype = type;
		time.setCycleCount(Timeline.INDEFINITE);
		time.getKeyFrames().add(new KeyFrame(Duration.millis(100), new EventHandler<ActionEvent>() {
			public void handle(ActionEvent event) {
				if (direction) {
					startPoint++;
					if (startPoint > width - length) 
						direction = false;
				} else {
					startPoint--;
					if (startPoint < length) 
						direction = true;
				}
			}
		}));
		time.play();
	}

	/**
	 * It feeds the waterfall by filling the last line based on the type of the feeder
	 * 
	 * @param line is the last line of the waterfall 
	 */
	public void feed(byte[] line) {
		switch(feedertype){
		case Random:
			randomFeed(line);
			break;
		case Sinusoidal:
			sinusoidalFeed(line);
			break;
		}
	}

	/**
	 * It randomly fills the last line with the numbers between 2 and 127
	 * 
	 * @param line is the last line of the waterfall 
	 */
	private void randomFeed(byte[] line) {
		Random random = new Random();
		for (int i = 0; i < width; i++) {
			line[i] = (byte) (random.nextInt(125) + 2);
		}	
	}

	/**
	 * It fills the last line with a shifting sinusoidal intensity plus random noise
	 *  
	 * @param line is the last line of the waterfall
	 */
	private void sinusoidalFeed(byte[] line) {
		Random random = new Random();
		int intensity = 0;
		for (int i = 0; i < width; i++) {
			double noise = random.nextInt(50);
			if (i > startPoint && i < startPoint + length) {
				intensity = (int) (75 * Math.sin((Math.PI) * (i - startPoint)/length)); 
			}
			else
				intensity = 0;
			line[i] = (byte) (noise + intensity + 2);
		}	

	}
}
